package org.budo.graph.entity;

import java.io.Serializable;

import org.budo.ehcache.config.annotation.entity.EhCacheConfigEntity;
import org.budo.graph.service.util.EhcacheStatisticsUtil;

import lombok.NoArgsConstructor;
import net.sf.ehcache.Cache;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.statistics.StatisticsGateway;

/**
 * @author li
 */
@NoArgsConstructor
public class EhcacheStatistics implements Serializable {
    private static final long serialVersionUID = 1873944701630217352L;

    private Cache cache;

    public EhcacheStatistics(Cache cache) {
        this.cache = cache;
    }

    public Boolean getConfigGraph() {
        EhCacheConfigEntity configEntity = this.getConfigEntity();
        return null != configEntity && configEntity.getGraph();
    }

    public EhCacheConfigEntity getConfigEntity() {
        String cacheName = this.getCacheName();
        return EhcacheStatisticsUtil.getEhCacheConfigEntity(cacheName);
    }

    public StatisticsGateway getStatistics() {
        if (null == this.cache) {
            return null;
        }

        return this.cache.getStatistics();
    }

    public CacheConfiguration getConfiguration() {
        if (null == this.cache) {
            return null;
        }

        return this.cache.getCacheConfiguration();
    }

    public String getCacheName() {
        if (null == this.cache) {
            return null;
        }

        return this.cache.getName();
    }

    public Integer getKeyCount() {
        if (null == this.cache) {
            return null;
        }

        return this.cache.getKeys().size();
    }

    public Long getCacheHitCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheHitCount();
    }

    public Long getLocalHeapHitCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.localHeapHitCount();
    }

    public Long getMaxEntriesLocalDisk() {
        CacheConfiguration configuration = this.getConfiguration();
        if (null == configuration) {
            return null;
        }

        return configuration.getMaxEntriesLocalDisk();
    }

    public Long getLocalDiskHitCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.localDiskHitCount();
    }

    public Long getCacheMissCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheMissCount();
    }

    public Long getLocalHeapMissCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.localHeapMissCount();
    }

    public Long getCacheMissExpiredCount() {
        StatisticsGateway statistics = this.getStatistics();
        return statistics.cacheMissExpiredCount();
    }

    public Long getCacheMissNotFoundCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheMissNotFoundCount();
    }

    public Long getCachePutCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cachePutCount();
    }

    public Long getLocalHeapPutCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.localHeapPutCount();
    }

    public Long getCachePutAddedCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cachePutAddedCount();
    }

    public Long getLocalHeapPutAddedCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.localHeapPutAddedCount();
    }

    public Long getCacheRemoveCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheRemoveCount();
    }

    public Long getCacheEvictedCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheEvictedCount();
    }

    public Long getCacheExpiredCount() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        return statistics.cacheExpiredCount();
    }

    public Long getTimeToLiveSeconds() {
        CacheConfiguration configuration = this.getConfiguration();
        if (null == configuration) {
            return null;
        }

        return configuration.getTimeToLiveSeconds();
    }

    public Long getTimeToIdleSeconds() {
        CacheConfiguration configuration = this.getConfiguration();
        if (null == configuration) {
            return null;
        }

        return configuration.getTimeToIdleSeconds();
    }

    public Long getMaxEntriesLocalHeap() {
        CacheConfiguration configuration = this.getConfiguration();
        if (null == configuration) {
            return null;
        }

        return configuration.getMaxEntriesLocalHeap();
    }

    public Double getMissExpiredRatio() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        long cacheHitCount = statistics.cacheHitCount();
        double denominator = cacheHitCount != 0 ? cacheHitCount : 1;

        long cacheMissExpiredCount = statistics.cacheMissExpiredCount();
        return (100 * cacheMissExpiredCount) / denominator;
    }

    public Double getMissNotFoundRatio() {
        StatisticsGateway statistics = this.getStatistics();
        if (null == statistics) {
            return null;
        }

        long cacheHitCount = statistics.cacheHitCount();
        double denominator = cacheHitCount != 0 ? cacheHitCount : 1;

        long cacheMissNotFoundCount = statistics.cacheMissNotFoundCount();
        return (100 * cacheMissNotFoundCount) / denominator;
    }
}